package com.yanqu.xiuxian.gameserver.tripletown.logic;

import com.yanqu.xiuxian.gameserver.tripletown.entity.Block;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class BlockLogic {

    /**
     * 校验存在
     */
    public static boolean validExisted(int[][] blockList, int fromX, int fromY, int toX, int toY) {
        return existed(blockList, fromX, fromY) && existed(blockList, toX, toY);
    }

    /**
     * 是否存在
     */
    public static boolean existed(int[][] blockList, Block block) {
        return existed(blockList, block.getX(), block.getY());
    }

    /**
     * 是否存在
     */
    public static boolean existed(int[][] blockList, int x, int y) {
        return x >= 0 && y >= 0 && y < blockList.length && x < blockList[y].length;
    }

    /**
     * 是否为炸弹
     */
    public static boolean isBomb(int color) {
        return color == 9 || color == 10;
    }

    /**
     * 是否为炸弹
     */
    public static boolean isBomb(Block block) {
        return isBomb(block.getC());
    }

    /**
     * 校验交换
     */
    public static boolean validExchange(int fromX, int fromY, int toX, int toY) {
        return (Math.abs(fromX - toX) == 1 && fromY == toY || Math.abs(fromY - toY) == 1 && fromX == toX);
    }

    /**
     * 交换方块
     */
    public static void exchange(int[][] blockList, int x1, int y1, int x2, int y2) {
        int tmp = blockList[y1][x1];
        blockList[y1][x1] = blockList[y2][x2];
        blockList[y2][x2] = tmp;
    }

    /**
     * 复制
     */
    public static int[][] copy(int[][] list) {
        int[][] result = new int[list.length][];
        for (int i = 0; i < list.length; i++) {
            result[i] = list[i].clone();
        }
        return result;
    }

    /**
     * 相同颜色分组排序（不含被炸弹炸的）
     *
     * @return Map<颜色, List < 每组数据>>
     */
    public static Map<Integer, List<List<Block>>> groupSortSameColor(Map<Integer, Map<Integer, Block>> eliminateMap) {
        // 【自然消除的分组】
        Map<Integer, List<List<Block>>> mapListList = new ConcurrentHashMap<>();
        for (Map<Integer, Block> blockMap : eliminateMap.values()) {
            for (Block block : blockMap.values()) {
                if (BlockLogic.isBomb(block) || !block.isEliminate()) {
                    continue;
                }
                if (!mapListList.containsKey(block.getC())) {
                    mapListList.put(block.getC(), new ArrayList<>());
                }

                List<List<Block>> listList = mapListList.get(block.getC());
                List<Integer> adjoinIndexList = new ArrayList<>();
                for (int i = 0; i < listList.size(); i++) {
                    List<Block> list = listList.get(i);
                    for (Block block1 : list) {
                        if (block1.getC() == block.getC() && isBlockAdjoin(block1, block)) {
                            adjoinIndexList.add(i);
                            break;
                        }
                    }
                }

                List<Block> list = new ArrayList<>();
                list.add(block);
                for (Integer index : adjoinIndexList) {
                    list.addAll(listList.get(index));
                }
                for (int i = adjoinIndexList.size() - 1; i >= 0; i--) {
                    listList.remove((int) adjoinIndexList.get(i));
                }
                listList.add(list);
            }
        }

        // 【每组小到大排序】
        for (List<List<Block>> value : mapListList.values()) {
            for (List<Block> blockList : value) {
                blockList.sort(Comparator.comparingInt(Block::getY)
                        .thenComparingInt(Block::getX)
                );
            }
        }
        return mapListList;
    }

    public static List<Block> calColorList(int[][] blockList, int x, int y) {
        return calColorList(blockList, blockList[y][x]);
    }

    public static List<Block> calColorList(int[][] blockList, int color) {
        List<Block> list = new ArrayList<>();
        for (int y = 0; y < blockList.length; y++) {
            for (int x = 0; x < blockList[y].length; x++) {
                if (blockList[y][x] == color) {
                    list.add(new Block(x, y, blockList[y][x]));
                }
            }
        }
        return list;
    }

    /**
     * 方块是否相邻
     */
    public static boolean isBlockAdjoin(Block block1, Block block2) {
        int subY = Math.abs(block1.getY() - block2.getY());
        int subX = Math.abs(block1.getX() - block2.getX());
        return subY == 1 && subX == 0 || subY == 0 && subX == 1;
    }

    public static int getMostColor(int[][] blockList) {
        int color = 0;
        int count = 0;
        Map<Integer, Integer> colorCountMap = getColorCountMap(blockList);
        for (Map.Entry<Integer, Integer> colorCountEntry : colorCountMap.entrySet()) {
            if (colorCountEntry.getValue() > count) {
                color = colorCountEntry.getKey();
                count = colorCountEntry.getValue();
            }
        }
        return color;
    }

    public static Map<Integer, Integer> getColorCountMap(int[][] blockList) {
        Map<Integer, Integer> colorCountMap = new HashMap<>();
        for (int y = 0; y < blockList.length; y++) {
            for (int x = 0; x < blockList[y].length; x++) {
                colorCountMap.merge(blockList[y][x], 1, Integer::sum);
            }
        }
        return colorCountMap;
    }

    public static Block getFirstColorBlock(int[][] blockList, int color) {
        for (int y = 0; y < blockList.length; y++) {
            for (int x = 0; x < blockList[y].length; x++) {
                if (blockList[y][x] == color) {
                    return new Block(x, y, color);
                }
            }
        }
        return null;
    }

}
